home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume15 / olvwm-3.0 / part14 < prev    next >
Encoding:
Internet Message Format  |  1992-02-03  |  55.2 KB

  1. Path: uunet!sun-barr!ames!pasteur!nntp
  2. From: scott.oaks@East.Sun.COM (Scott Oaks)
  3. Newsgroups: comp.sources.x
  4. Subject: v15i160: OpenLook Virtual Window Mgr (3.0), Part14/21
  5. Message-ID: <1992Feb4.135858.7875@pasteur.Berkeley.EDU>
  6. Date: 4 Feb 92 13:58:58 GMT
  7. References: <csx-15i147-olvwm-3.0@uunet.UU.NET>
  8. Sender: dcmartin@msi.com (David C. Martin - Moderator)
  9. Organization: University of California, at Berkeley
  10. Lines: 1911
  11. Approved: dcmartin@msi.com
  12. Nntp-Posting-Host: postgres.berkeley.edu
  13.  
  14. Submitted-by: scott.oaks@East.Sun.COM (Scott Oaks)
  15. Posting-number: Volume 15, Issue 160
  16. Archive-name: olvwm-3.0/part14
  17.  
  18. # This is a shell archive.  Remove anything before this line, then feed it
  19. # into a shell via "sh file" or similar.  To overwrite existing files,
  20. # type "sh file -c".
  21. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  22. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  23. # If this archive is complete, you will see the following message at the end:
  24. #        "End of archive 14 (of 21)."
  25. # Contents:  Notice.c ol_button.c vdm.icon
  26. # Wrapped by dcmartin@fascet on Tue Jan 14 05:54:46 1992
  27. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  28. if test -f 'Notice.c' -a "${1}" != "-c" ; then 
  29.   echo shar: Will not clobber existing file \"'Notice.c'\"
  30. else
  31. echo shar: Extracting \"'Notice.c'\" \(22967 characters\)
  32. sed "s/^X//" >'Notice.c' <<'END_OF_FILE'
  33. X/*
  34. X *      (c) Copyright 1989, 1990 Sun Microsystems, Inc. Sun design patents
  35. X *      pending in the U.S. and foreign countries. See LEGAL_NOTICE
  36. X *      file for terms of the license.
  37. X */
  38. X
  39. X#ident "@(#)Notice.c    1.1 olvwm version 1/3/92"
  40. X
  41. X/*
  42. X * Based on
  43. X#ident    "@(#)Notice.c    26.19    91/09/14 SMI"
  44. X *
  45. X */
  46. X
  47. X#include <errno.h>
  48. X#include <stdio.h>
  49. X#include <ctype.h>
  50. X#include <X11/Xos.h>
  51. X#include <X11/Xlib.h>
  52. X#include <X11/Xutil.h>
  53. X#include <olgx/olgx.h>
  54. X
  55. X#include "i18n.h"
  56. X#include "ollocale.h"
  57. X#include "olwm.h"
  58. X#include "win.h"
  59. X#include "notice.h"
  60. X#include "globals.h"
  61. X#include "mem.h"
  62. X#include "events.h"
  63. X
  64. X
  65. Xextern int        PointInRect();
  66. Xextern SemanticAction     FindKeyboardAction();
  67. X
  68. X#define    NOTICE_EVENT_MASK    ( ButtonPressMask | ButtonReleaseMask \
  69. X                  | PointerMotionMask | KeyPressMask \
  70. X                  | ExposureMask )
  71. X#define    NOTICE_ATTR_MASK    ( CWBorderPixel | CWColormap | \
  72. X                  CWEventMask | CWSaveUnder )
  73. X
  74. X/* difference between inside beveled box and outside beveled box */
  75. X#define BORDER_WIDTH        5    
  76. X#define    MIN_BOX_SIDE        ( 15 + BORDER_WIDTH )    /* betw side & text */
  77. X#define    MIN_BOX_TOP        ( 15 + BORDER_WIDTH )    /* betw top & text */
  78. X#define    MIN_BOX_BOTTOM        ( 15 + BORDER_WIDTH )    /* betw bot & text */
  79. X#define MIN_BUTTON_SPACE    15        /* space between buttons */
  80. X#define MIN_BUTTON_VSPACE    15        /* space above buttons */
  81. X#define MIN_STRING_VSPACE    5        /* space above/below strings */
  82. X#define OUTLINE_WIDTH        2        /* thickness of 2D border */
  83. X
  84. Xtypedef struct {
  85. X    int        x;
  86. X    int        y;
  87. X    unsigned int    width;        /* space taken up by text */
  88. X    unsigned int    fullWidth;    /* width including endcaps */
  89. X    char        accelerator;    /* mouseless accelerator key */
  90. X} noticeButtonDetails;
  91. X
  92. Xtypedef struct {
  93. X    Display            *dpy;
  94. X    ScreenInfo        *scrInfo;
  95. X    NoticeBox        *noticeBox;
  96. X    int            numStrings;
  97. X    char            **stringText;
  98. X    Window            window;
  99. X    unsigned int        buttonHeight;
  100. X    unsigned int        fontHeight;
  101. X    unsigned int        boxHeight;
  102. X    unsigned int        boxWidth;
  103. X    int            x;
  104. X    int            y;
  105. X    int            totalButtonWidth;
  106. X    noticeButtonDetails    *buttonInfo;
  107. X    int            buttonSelected;
  108. X    int            buttonFocus;
  109. X    int            buttonDown;
  110. X    int            buttonDrawnDown;
  111. X    void            (*noticeCallback)();
  112. X    int            pointerX,pointerY;
  113. X    Bool            ignoreExpose;
  114. X    Bool            warped;
  115. X} noticeBoxDetails;
  116. X
  117. Xstatic void         calculateBoxDimensions();
  118. Xstatic void         drawNoticeBox();
  119. Xstatic void        noticeDone();
  120. Xstatic int        noticeInterposer();
  121. X
  122. XnoticeBoxDetails    *CreateNoticeBox();
  123. Xvoid            DestroyNoticeBox();
  124. Xvoid            ShowNoticeBox();
  125. X
  126. X
  127. X/******************************************************************
  128. X *            Private Draw Functions
  129. X ******************************************************************/
  130. X
  131. X/*
  132. X * calculateBoxDimensions -- determine size of box needed, etc. based on
  133. X *         information passed in in noticeBox structure.  Return
  134. X *        values in boxDetails structure.
  135. X */
  136. Xstatic void
  137. XcalculateBoxDimensions( noticeBox, boxDetails )
  138. XNoticeBox        *noticeBox;
  139. XnoticeBoxDetails    *boxDetails;
  140. X{
  141. X    int        screen = boxDetails->scrInfo->screen;
  142. X    unsigned int    displayWidth, displayHeight;
  143. X    int        longestStringLength = 0;
  144. X    int        totalButtonWidth = 0;
  145. X    Graphics_info    *gisButton = boxDetails->scrInfo->gi[BUTTON_GINFO];
  146. X    int        ii;
  147. X    char        *tok,*str;
  148. Xstatic    char        *sep = "\n";
  149. Xextern    char        *strtok();
  150. X
  151. X    boxDetails->fontHeight = GRV.TextFontInfo->ascent + 
  152. X                    GRV.TextFontInfo->descent;
  153. X
  154. X    /* calculate the width of the text which appears inside the button */
  155. X    for ( ii = 0 ; ii < noticeBox->numButtons ; ii++ ) {
  156. X        boxDetails->buttonInfo[ii].width = 
  157. X            XTextWidth( GRV.ButtonFontInfo, 
  158. X                    noticeBox->buttonText[ii], 
  159. X                    strlen(noticeBox->buttonText[ii]) );
  160. X        boxDetails->buttonInfo[ii].fullWidth = 
  161. X            boxDetails->buttonInfo[ii].width 
  162. X                + 2 * ButtonEndcap_Width(gisButton);
  163. X    }
  164. X
  165. X    /* make the key accelerators from the button text string */
  166. X    for ( ii = 0 ; ii < noticeBox->numButtons ; ii++ ) {
  167. X        boxDetails->buttonInfo[ii].accelerator = 
  168. X            tolower(*noticeBox->buttonText[ii]);
  169. X    }
  170. X
  171. X    /* add together widths of all the buttons */
  172. X    for ( ii = 0 ; ii < noticeBox->numButtons ; ii++ )
  173. X        totalButtonWidth += boxDetails->buttonInfo[ii].fullWidth;
  174. X    boxDetails->totalButtonWidth = totalButtonWidth;
  175. X
  176. X    /*
  177. X     * Split the msg string into individual strings using newlines
  178. X     */
  179. X
  180. X    /* count the newlines in the msg starting with one */
  181. X    for (ii = 1, str = noticeBox->msgText; *str != '\0'; str++) {
  182. X        if (*str == '\n')
  183. X            ii++;
  184. X    }
  185. X
  186. X    /* alloc the string pointer array */
  187. X    boxDetails->numStrings = ii;
  188. X    boxDetails->stringText = 
  189. X        (char **)MemAlloc(boxDetails->numStrings * sizeof(char *));
  190. X
  191. X    /* split the msg string into separate string in stringText array */
  192. X    str = MemNewString(noticeBox->msgText);
  193. X    for (ii=0, tok=strtok(str,sep); tok; tok=strtok((char *)NULL,sep)) {
  194. X        boxDetails->stringText[ii++] = MemNewString(tok);
  195. X    }
  196. X    MemFree(str);
  197. X
  198. X    /* figure out which descriptive string is longest */
  199. X    for ( ii = 0 ; ii < boxDetails->numStrings ; ii++ )
  200. X        longestStringLength = 
  201. X            MAX( longestStringLength,
  202. X                 XTextWidth( GRV.TextFontInfo, 
  203. X                         boxDetails->stringText[ii], 
  204. X                         strlen(boxDetails->stringText[ii]) ) );
  205. X
  206. X    /* 
  207. X     * REMIND: this calculation assumes all the buttons are
  208. X     * on the same line
  209. X     */
  210. X    boxDetails->boxWidth = 2 * MIN_BOX_SIDE 
  211. X           + MAX( longestStringLength,
  212. X              totalButtonWidth + 
  213. X                  /* amount of space between all the buttons */
  214. X                  MIN_BUTTON_SPACE * (noticeBox->numButtons - 1) );
  215. X
  216. X    boxDetails->buttonHeight = Button_Height(gisButton);
  217. X
  218. X    boxDetails->boxHeight = MIN_BOX_TOP + MIN_BOX_BOTTOM
  219. X            + ( boxDetails->numStrings * boxDetails->fontHeight )
  220. X            /* amount of space vertically between all the strings */
  221. X            + ( (boxDetails->numStrings - 1) * MIN_STRING_VSPACE )
  222. X            + MIN_BUTTON_VSPACE + boxDetails->buttonHeight;
  223. X    displayWidth = DisplayWidth( boxDetails->dpy, screen );
  224. X    displayHeight = DisplayHeight( boxDetails->dpy, screen );
  225. X
  226. X    /* if not set, create default "origin" for box: centered */
  227. X    boxDetails->x = ( noticeBox->boxX == -1 ) 
  228. X                ? (int)( displayWidth - boxDetails->boxWidth )/2 
  229. X                : noticeBox->boxX ;
  230. X    boxDetails->y = ( noticeBox->boxY == -1 ) 
  231. X                ? (int)( displayHeight - boxDetails->boxHeight )/2 
  232. X                : noticeBox->boxY ;
  233. X
  234. X}
  235. X
  236. X/*
  237. X * drawLocationCursor
  238. X */
  239. Xstatic void
  240. XdrawLocationCursor(details,btn,erase)
  241. X    noticeBoxDetails *details;
  242. X    int        btn;
  243. X    Bool        erase;
  244. X{
  245. Xstatic    XPoint    pts[] = { 0,0, 6,11, -12,0 };
  246. X    GC    gc ;
  247. X
  248. X    pts[0].x = details->buttonInfo[btn].x +
  249. X           details->buttonInfo[btn].fullWidth/2;
  250. X    pts[0].y = details->buttonInfo[btn].y +
  251. X           details->buttonHeight - 7;
  252. X
  253. X    if (erase)
  254. X        gc = details->scrInfo->gc[WINDOW_GC];
  255. X    else
  256. X        gc = details->scrInfo->gc[FOREGROUND_GC];
  257. X
  258. X    XFillPolygon(details->dpy,details->window,
  259. X            gc,pts,3,Convex,CoordModePrevious);
  260. X}
  261. X
  262. X/*
  263. X * drawButton
  264. X */
  265. Xstatic void
  266. XdrawButton(noticeBox,details,btn,btnState)
  267. XNoticeBox        *noticeBox;
  268. XnoticeBoxDetails    *details;
  269. Xint            btn;
  270. Xint            btnState;
  271. X{
  272. X    Graphics_info    *gisButton = details->scrInfo->gi[BUTTON_GINFO];
  273. X    int        buttonState;
  274. X
  275. X    if (noticeBox->defaultButton == btn) {
  276. X        buttonState = btnState;
  277. X        buttonState |= OLGX_DEFAULT;
  278. X    } else {
  279. X        buttonState = btnState;
  280. X    }
  281. X
  282. X    if (details->buttonFocus == btn)
  283. X        drawLocationCursor(details,btn,(buttonState & OLGX_ERASE));
  284. X
  285. X    olgx_draw_button(gisButton,details->window,
  286. X            details->buttonInfo[btn].x,details->buttonInfo[btn].y,
  287. X            details->buttonInfo[btn].fullWidth,0,
  288. X            noticeBox->buttonText[btn],buttonState);
  289. X}
  290. X
  291. X/*
  292. X * drawNoticeBox -- draw box outline, strings, and buttons using information
  293. X *        in noticeBox and boxDetails structures which are passed in.
  294. X *        Location of buttons (x, y) are set in boxDetails structure
  295. X *        for use later (mouse warping, determining pointer position).
  296. X */
  297. Xstatic void
  298. XdrawNoticeBox( noticeBox, boxDetails )
  299. XNoticeBox        *noticeBox;
  300. XnoticeBoxDetails    *boxDetails;
  301. X{
  302. X    int    ii;
  303. X    int    buttonX, buttonY;
  304. X    int    buttonState;        /* OLGX_NORMAL or OLGX_DEFAULT */
  305. X    Graphics_info    *gisText = boxDetails->scrInfo->gi[TEXT_GINFO];
  306. X    Graphics_info    *gisButton = boxDetails->scrInfo->gi[BUTTON_GINFO];
  307. X
  308. X    /* frame outline */
  309. X    if (GRV.F3dFrames) {
  310. X
  311. X        /* fill it in, because olgx doesn't fill in 2D */
  312. X        if (!boxDetails->scrInfo->use3D)
  313. X        XFillRectangle(boxDetails->dpy, boxDetails->window,
  314. X                   boxDetails->scrInfo->gc[WINDOW_GC], 0, 0,
  315. X                   boxDetails->boxWidth, boxDetails->boxHeight);
  316. X
  317. X        olgx_draw_box(gisButton,
  318. X        boxDetails->window, 0, 0, 
  319. X        boxDetails->boxWidth, boxDetails->boxHeight, 
  320. X              OLGX_NORMAL, True );
  321. X
  322. X    } else {
  323. X        GC gc = boxDetails->scrInfo->gc[BORDER_GC];
  324. X
  325. X        XFillRectangle(boxDetails->dpy, boxDetails->window,
  326. X               boxDetails->scrInfo->gc[WINDOW_GC], 0, 0,
  327. X               boxDetails->boxWidth, boxDetails->boxHeight);
  328. X
  329. X        XFillRectangle(boxDetails->dpy, boxDetails->window, gc,
  330. X               0, 0, boxDetails->boxWidth, OUTLINE_WIDTH);
  331. X        XFillRectangle(boxDetails->dpy, boxDetails->window, gc,
  332. X               0, boxDetails->boxHeight - OUTLINE_WIDTH,
  333. X               boxDetails->boxWidth, OUTLINE_WIDTH);
  334. X        XFillRectangle(boxDetails->dpy, boxDetails->window, gc,
  335. X               0, OUTLINE_WIDTH, OUTLINE_WIDTH,
  336. X               boxDetails->boxHeight - 2*OUTLINE_WIDTH);
  337. X        XFillRectangle(boxDetails->dpy, boxDetails->window, gc,
  338. X               boxDetails->boxWidth - OUTLINE_WIDTH, OUTLINE_WIDTH,
  339. X               OUTLINE_WIDTH,
  340. X               boxDetails->boxHeight - 2*OUTLINE_WIDTH);
  341. X    }
  342. X
  343. X    if (boxDetails->scrInfo->use3D) {
  344. X        /* REMIND: this is a hack to draw a chiseled box */
  345. X        olgx_draw_box(gisButton,
  346. X        boxDetails->window, BORDER_WIDTH, BORDER_WIDTH, 
  347. X        boxDetails->boxWidth - 2 * BORDER_WIDTH, 
  348. X        boxDetails->boxHeight - 2 * BORDER_WIDTH, 
  349. X        OLGX_INVOKED, False);
  350. X        olgx_draw_box(gisButton,
  351. X        boxDetails->window, BORDER_WIDTH+1, BORDER_WIDTH+1,
  352. X        boxDetails->boxWidth - 2 * BORDER_WIDTH - 2,
  353. X        boxDetails->boxHeight - 2 * BORDER_WIDTH - 2,
  354. X        OLGX_NORMAL, False);
  355. X    } else {
  356. X        olgx_draw_box(gisButton,
  357. X        boxDetails->window, BORDER_WIDTH, BORDER_WIDTH, 
  358. X        boxDetails->boxWidth - 2 * BORDER_WIDTH, 
  359. X        boxDetails->boxHeight - 2 * BORDER_WIDTH, 
  360. X        OLGX_NORMAL, True);
  361. X    }
  362. X
  363. X    /* draw descriptive text 
  364. X     * REMIND: all strings are along the left edge (MIN_BOX_SIDE) 
  365. X     */
  366. X    for ( ii = 0 ; ii < boxDetails->numStrings ; ii++ )
  367. X        olgx_draw_text(gisText,
  368. X            boxDetails->window, boxDetails->stringText[ii], 
  369. X            MIN_BOX_SIDE,
  370. X            /* need to move each line further down the screen */
  371. X            MIN_BOX_TOP + GRV.TextFontInfo->ascent * ( ii + 1 )
  372. X                + ( MIN_STRING_VSPACE * ii ),
  373. X            0, False, OLGX_NORMAL );
  374. X
  375. X    /* put buttons in - notice that it's a single row */
  376. X    /* row of buttons should be centered within available space,
  377. X     * assuming MIN_BUTTON_SPACE between each of the them
  378. X     */
  379. X    buttonX = ( boxDetails->boxWidth - (boxDetails->totalButtonWidth 
  380. X                + MIN_BUTTON_SPACE * (noticeBox->numButtons - 1)) )/2;
  381. X    /* this calculates from the bottom of the box */
  382. X    buttonY = ( boxDetails->boxHeight - 
  383. X            ( MIN_BOX_BOTTOM + boxDetails->buttonHeight ) );
  384. X    for ( ii = 0 ; ii < noticeBox->numButtons ; ii++ )
  385. X    {
  386. X        if ( noticeBox->defaultButton == ii )
  387. X            buttonState = OLGX_DEFAULT;
  388. X        else
  389. X            buttonState = OLGX_NORMAL;
  390. X
  391. X        /* save button's x, y values for use later */
  392. X        boxDetails->buttonInfo[ii].x = buttonX;
  393. X        boxDetails->buttonInfo[ii].y = buttonY;
  394. X
  395. X        olgx_draw_button(gisButton,
  396. X            boxDetails->window, buttonX, buttonY,
  397. X            boxDetails->buttonInfo[ii].fullWidth, 0,
  398. X            noticeBox->buttonText[ii], 
  399. X            buttonState );
  400. X
  401. X        /* set up buttonX for next button */ 
  402. X        buttonX = buttonX + boxDetails->buttonInfo[ii].fullWidth
  403. X                + MIN_BUTTON_SPACE;
  404. X    }
  405. X
  406. X    drawLocationCursor(boxDetails,boxDetails->buttonFocus,False);
  407. X}
  408. X
  409. X/******************************************************************
  410. X *            Private Event Functions
  411. X ******************************************************************/
  412. X
  413. X
  414. X/*
  415. X * setButtonFocus - sets the focus button to the passed value and
  416. X *    redraws the necessary buttons.
  417. X */
  418. Xstatic void
  419. XsetButtonFocus(details,newFocus)
  420. XnoticeBoxDetails    *details;
  421. Xint            newFocus;
  422. X{
  423. X    int        oldFocus = details->buttonFocus;
  424. X
  425. X    drawButton(details->noticeBox,details,oldFocus,OLGX_ERASE);
  426. X    details->buttonFocus = newFocus;
  427. X    drawButton(details->noticeBox,details,newFocus,OLGX_NORMAL);
  428. X}
  429. X
  430. X/*
  431. X * moveButtonFocus - moves the focus button in the indicated direction
  432. X *    and wraps around then first and last buttons.
  433. X */
  434. Xstatic void
  435. XmoveButtonFocus(details,dir)
  436. XnoticeBoxDetails    *details;
  437. Xint            dir;
  438. X{
  439. X    NoticeBox    *noticeBox = details->noticeBox;
  440. X    int        newFocus = details->buttonFocus;
  441. X
  442. X    if (noticeBox->numButtons == 1)
  443. X        return;
  444. X
  445. X    newFocus += dir;
  446. X
  447. X    if (newFocus >= noticeBox->numButtons)
  448. X        newFocus = 0;
  449. X    else if (newFocus < 0)
  450. X        newFocus = noticeBox->numButtons-1;
  451. X
  452. X    setButtonFocus(details,newFocus);
  453. X}
  454. X
  455. X/*
  456. X * keyAccelerator - if the key event matches one of the button accelerators
  457. X *    return True and set button to the accelerated button.
  458. X */
  459. Xstatic Bool
  460. XkeyAccelerator(key,details,button)
  461. X    XKeyEvent    *key;
  462. X    noticeBoxDetails *details;
  463. X    int        *button;        /* RETURN */
  464. X{
  465. X    NoticeBox    *noticeBox = details->noticeBox;
  466. X    char        accel,str[10];
  467. X    KeySym        keySym;
  468. X    int        keyCount,i;
  469. X
  470. X    keyCount = XLookupString(key,str,10,&keySym,NULL);
  471. X
  472. X    if (keyCount != 1)
  473. X        return False;
  474. X
  475. X    accel = tolower(str[0]);
  476. X
  477. X    for (i = 0; i < noticeBox->numButtons; i++) {
  478. X        if (accel == details->buttonInfo[i].accelerator) {
  479. X            *button = i;
  480. X            return True;
  481. X        }
  482. X    }
  483. X
  484. X    return False;
  485. X}
  486. X
  487. X/*
  488. X * pointInButton - True if the button is it the passed button number
  489. X */
  490. Xstatic Bool
  491. XpointInButton(event,details,btn)
  492. X    XButtonEvent    *event;
  493. X    noticeBoxDetails *details;
  494. X    int        btn;
  495. X{
  496. X    return PointInRect(event->x,event->y,
  497. X        details->buttonInfo[btn].x,details->buttonInfo[btn].y,
  498. X        details->buttonInfo[btn].fullWidth,details->buttonHeight);
  499. X}
  500. X
  501. X/*
  502. X * noticeInterposer - event handler for notices
  503. X */
  504. Xstatic int
  505. XnoticeInterposer(dpy,event,win,details)
  506. XDisplay            *dpy;
  507. XXEvent            *event;
  508. Xvoid            *win;
  509. XnoticeBoxDetails    *details;
  510. X{
  511. X    NoticeBox    *noticeBox = details->noticeBox;
  512. X    int        ii,button,buttonState;
  513. X
  514. X    /*
  515. X     * Discard synthetic events
  516. X     */
  517. X    if (event->xany.send_event)
  518. X        return DISPOSE_USED;
  519. X
  520. X    switch (event->type) {
  521. X    case ButtonPress:
  522. X
  523. X        /* first check to see if we're even in the notice box */
  524. X        if (!PointInRect(event->xbutton.x,event->xbutton.y,
  525. X                 0,0,details->boxWidth,details->boxHeight))
  526. X            break;
  527. X
  528. X        /* if on one of the notice buttons, depress it */
  529. X        for ( ii = 0 ; ii < noticeBox->numButtons ; ii++ ) {
  530. X            if (pointInButton(event,details,ii)) {
  531. X                details->buttonDown = ii;
  532. X                details->buttonDrawnDown = True;
  533. X                drawButton(noticeBox,details,ii,OLGX_INVOKED);
  534. X                break;
  535. X            }
  536. X        }
  537. X        break;
  538. X
  539. X    case ButtonRelease:
  540. X        if (details->buttonDown < 0)
  541. X            break;
  542. X
  543. X        /* only a depressed button can be selected */
  544. X        if (pointInButton(event,details,details->buttonDown)) {
  545. X            details->buttonSelected = details->buttonDown;
  546. X            noticeDone(dpy,details);
  547. X
  548. X        /* else erase the depressed button and now unselected */
  549. X        } else {
  550. X            drawButton(noticeBox,details,
  551. X                   details->buttonDown,OLGX_ERASE);
  552. X            details->buttonDown = -1;
  553. X            details->buttonDrawnDown = False;
  554. X        }
  555. X        break;
  556. X        
  557. X    case MotionNotify:
  558. X        if ( details->buttonDown < 0 )
  559. X            break;
  560. X
  561. X        /* if moved out of depressed button erase it and cancel */
  562. X        if (!pointInButton(event,details,details->buttonDown)) {
  563. X            drawButton(noticeBox,details,
  564. X                   details->buttonDown,OLGX_ERASE);
  565. X            details->buttonDown = -1;
  566. X            details->buttonDrawnDown = False;
  567. X        }
  568. X        break;
  569. X
  570. X    case KeyPress:
  571. X        switch (FindKeyboardAction(dpy,event)) {
  572. X        case ACTION_EXEC_DEFAULT:
  573. X            details->buttonSelected = noticeBox->defaultButton;
  574. X            noticeDone(dpy,details);
  575. X            break;
  576. X        case ACTION_CANCEL:
  577. X        case ACTION_STOP:
  578. X            details->buttonSelected = NOTICE_CANCEL;
  579. X            noticeDone(dpy,details);
  580. X            break;
  581. X        case ACTION_SELECT:
  582. X            details->buttonSelected = details->buttonFocus;
  583. X            noticeDone(dpy,details);
  584. X            break;
  585. X        case ACTION_NEXT_ELEMENT:
  586. X        case ACTION_RIGHT:
  587. X            moveButtonFocus(details,1);
  588. X            break;
  589. X        case ACTION_PREVIOUS_ELEMENT:
  590. X        case ACTION_LEFT:
  591. X            moveButtonFocus(details,-1);
  592. X            break;
  593. X        case ACTION_FIRST_CONTROL:
  594. X            setButtonFocus(details,0);
  595. X            break;
  596. X        case ACTION_LAST_CONTROL:
  597. X            setButtonFocus(details,noticeBox->numButtons-1);
  598. X            break;
  599. X        default:
  600. X            if (keyAccelerator(event,details,&button))
  601. X                setButtonFocus(details,button);
  602. X            else
  603. X                KeyBeep(dpy,event);
  604. X            break;
  605. X        }
  606. X    case KeyRelease:
  607. X        return DISPOSE_USED;
  608. X
  609. X    case Expose:
  610. X        /*
  611. X         * Ignore the first expose, since we painted as soon as we 
  612. X         * mapped.  Otherwise, we really were exposed, so repaint.
  613. X         */
  614. X        if (event->xexpose.count == 0) {
  615. X            if (details->ignoreExpose)
  616. X            details->ignoreExpose = False;
  617. X            else
  618. X            drawNoticeBox(details->noticeBox,details);
  619. X        }
  620. X        return DISPOSE_USED;
  621. X
  622. X    default:
  623. X        return DISPOSE_DEFER;
  624. X    }
  625. X    return DISPOSE_USED;
  626. X}
  627. X
  628. X
  629. X
  630. X/*
  631. X * noticeDone()    -- warp pointer back, release grabs, remove interposer, call 
  632. X * the callback, and clean up the notice window.
  633. X */
  634. Xstatic void
  635. XnoticeDone(dpy,boxDetails)
  636. XDisplay            *dpy;
  637. XnoticeBoxDetails    *boxDetails;
  638. X{
  639. X    if (boxDetails->warped)
  640. X        XWarpPointer(dpy,None,boxDetails->scrInfo->rootid,
  641. X              0,0,0,0,boxDetails->pointerX,boxDetails->pointerY);
  642. X
  643. X    if (GRV.ServerGrabs)
  644. X        XUngrabServer(dpy);
  645. X    XUngrabKeyboard(dpy,CurrentTime);
  646. X    XUngrabPointer(dpy,CurrentTime);
  647. X
  648. X    UninstallInterposer();
  649. X
  650. X    if (boxDetails->noticeCallback)
  651. X        (*boxDetails->noticeCallback)(dpy,boxDetails->buttonSelected);
  652. X
  653. X    DestroyNoticeBox(boxDetails);
  654. X}
  655. X
  656. X
  657. X/******************************************************************
  658. X *            Global Functions
  659. X ******************************************************************/
  660. X
  661. X/*
  662. X * CreateNoticeBox -- create the notice box/button details and the window
  663. X */
  664. XnoticeBoxDetails *
  665. XCreateNoticeBox(dpy,screen,noticeBox,callback)
  666. X    Display        *dpy;
  667. X    int        screen;
  668. X    NoticeBox    *noticeBox;
  669. X    void        (*callback)();
  670. X{
  671. X    XSetWindowAttributes    attributes;
  672. X    noticeBoxDetails    *boxDetails;
  673. X    int            i,defaultButton;
  674. X
  675. X    /* 
  676. X     * Create box details and button details
  677. X     */
  678. X    boxDetails = MemNew(noticeBoxDetails);
  679. X    boxDetails->buttonInfo = 
  680. X        (noticeButtonDetails *)MemAlloc( noticeBox->numButtons 
  681. X            * (unsigned int)sizeof(noticeButtonDetails) );
  682. X    boxDetails->noticeBox = MemNew(NoticeBox);
  683. X
  684. X    /*
  685. X      * Init basic box details
  686. X     *  - copy the passed in noticeBox since this is interposition
  687. X     */
  688. X    boxDetails->dpy = dpy;
  689. X    boxDetails->scrInfo = GetScrInfoOfScreen(screen);
  690. X    boxDetails->noticeCallback = callback;
  691. X    *boxDetails->noticeBox = *noticeBox;
  692. X
  693. X    boxDetails->noticeBox->buttonText = 
  694. X            MemAlloc(noticeBox->numButtons * sizeof(char *));
  695. X
  696. X    for (i = 0; i < noticeBox->numButtons; i++)
  697. X        boxDetails->noticeBox->buttonText[i] = 
  698. X            MemNewString(noticeBox->buttonText[i]);
  699. X
  700. X    boxDetails->noticeBox->msgText = MemNewString(noticeBox->msgText);
  701. X
  702. X    /* 
  703. X     * Figure out size to make window and where to put it
  704. X     */
  705. X    calculateBoxDimensions(boxDetails->noticeBox,boxDetails); 
  706. X
  707. X    /* 
  708. X     * Set up window attributes structure
  709. X     */
  710. X    attributes.border_pixel = 0;
  711. X    attributes.colormap = boxDetails->scrInfo->colormap;
  712. X    attributes.event_mask = NOTICE_EVENT_MASK;
  713. X    attributes.save_under = True;
  714. X
  715. X    /* 
  716. X     * Create window
  717. X     */
  718. X    boxDetails->window = XCreateWindow(dpy,
  719. X                       RootWindow(dpy,screen),
  720. X                           boxDetails->x, boxDetails->y, 
  721. X                       boxDetails->boxWidth, 
  722. X                       boxDetails->boxHeight, 0, 
  723. X                       boxDetails->scrInfo->depth,
  724. X                       InputOutput,
  725. X                       boxDetails->scrInfo->visual, 
  726. X                           NOTICE_ATTR_MASK,
  727. X                           &attributes );
  728. X
  729. X    boxDetails->buttonSelected = -1;
  730. X    boxDetails->buttonFocus = noticeBox->defaultButton;
  731. X    boxDetails->buttonDown = -1;
  732. X    boxDetails->buttonDrawnDown = False;
  733. X    boxDetails->ignoreExpose = True;
  734. X    boxDetails->warped = False;
  735. X
  736. X    return boxDetails;
  737. X}
  738. X
  739. X/*
  740. X * DestroyNoticeBox -- destroys the notice box/button details and window
  741. X */
  742. Xvoid
  743. XDestroyNoticeBox(boxDetails)
  744. X    noticeBoxDetails    *boxDetails;
  745. X{
  746. X    int    i;
  747. X
  748. X    XDestroyWindow(boxDetails->dpy,boxDetails->window);
  749. X
  750. X    for (i=0; i<boxDetails->numStrings; i++) 
  751. X        MemFree(boxDetails->stringText[i]);
  752. X    MemFree(boxDetails->stringText);
  753. X    MemFree(boxDetails->buttonInfo);
  754. X    for (i=0; i<boxDetails->noticeBox->numButtons; i++)
  755. X        MemFree(boxDetails->noticeBox->buttonText[i]);
  756. X    MemFree(boxDetails->noticeBox->buttonText);
  757. X    MemFree(boxDetails->noticeBox->msgText);
  758. X    MemFree(boxDetails->noticeBox);
  759. X    MemFree(boxDetails);
  760. X}
  761. X    
  762. X/*
  763. X * ShowNoticeBox -- Brings up the notice box
  764. X */
  765. Xvoid
  766. XShowNoticeBox(dpy,details)
  767. X    Display            *dpy;
  768. X    noticeBoxDetails    *details;
  769. X{
  770. X    int            defaultButton;
  771. X    int            grabstat;
  772. X
  773. X    /*
  774. X     * Map the window, then grab the pointer, the keyboard, and the
  775. X     * server.  Return immediately if we couldn't grab the pointer, but
  776. X     * only issue a warning if we couldn't grab the keyboard.  We need to
  777. X     * map the window first, otherwise the grabs will fail.
  778. X     */
  779. X    XMapRaised(dpy,details->window);
  780. X    grabstat = XGrabPointer(dpy, details->window, False,
  781. X                ButtonPressMask | ButtonReleaseMask,
  782. X                GrabModeAsync, GrabModeAsync,
  783. X                None, None, CurrentTime);
  784. X
  785. X    if (grabstat != GrabSuccess) {
  786. X        noticeDone(dpy, details);
  787. X        ErrorWarning(gettext("failed to grab pointer"));
  788. X        return;
  789. X    }
  790. X
  791. X    grabstat = XGrabKeyboard(dpy, details->window, False, 
  792. X                 GrabModeAsync, GrabModeAsync, CurrentTime);
  793. X    if (grabstat != GrabSuccess)
  794. X        ErrorWarning(gettext("failed to grab keyboard"));
  795. X
  796. X    if (GRV.ServerGrabs)
  797. X        XGrabServer(dpy);
  798. X
  799. X    /*
  800. X     * Draw notice window immediately.  The first expose event is ignored, 
  801. X     * so there is no redundant repaint.
  802. X     */
  803. X    drawNoticeBox(details->noticeBox,details);
  804. X
  805. X    if (GRV.Beep != BeepNever)
  806. X        XBell(dpy,100);
  807. X
  808. X    if (GRV.PopupJumpCursor) {
  809. X        int            dummyInt;
  810. X        unsigned int        dummyUInt;
  811. X        Window            dummyWin;
  812. X
  813. X        /* save current mouse position */
  814. X        XQueryPointer(dpy,details->scrInfo->rootid,
  815. X               &dummyWin,&dummyWin,
  816. X               &(details->pointerX),&(details->pointerY),
  817. X               &dummyInt,&dummyInt,&dummyUInt);
  818. X
  819. X        /* warp pointer to default button */
  820. X        defaultButton = details->noticeBox->defaultButton;
  821. X
  822. X            XWarpPointer(dpy,None,details->window,0,0,0,0, 
  823. X              details->buttonInfo[defaultButton].x
  824. X                + details->buttonInfo[defaultButton].fullWidth/2, 
  825. X              details->buttonInfo[defaultButton].y
  826. X                + details->buttonHeight/2 );
  827. X
  828. X        details->warped = True;
  829. X    }
  830. X
  831. X    InstallInterposer(noticeInterposer,details);
  832. X}
  833. X
  834. X
  835. X
  836. X/*
  837. X * UseNoticeBox -- pop up a box which forces the user to answer
  838. X *           a question using the buttons
  839. X *
  840. X * Arguments:
  841. X *    dpy        - pointer to current display
  842. X *    screen        - index to current screen
  843. X *    noticeBox   - pointer to NoticeBox structure:
  844. X *        numButtons    (number of buttons)
  845. X *        defaultButton    (index into buttonText for mouse warp)
  846. X *        buttonText    (array of strings for button text)
  847. X *        msgText        (msg string for description w/ newlines)
  848. X *        boxX        (box origin (-1 =use default/centered))
  849. X *        boxY        (box origin (-1 =use default/centered))
  850. X *
  851. X *    Default placement of the box is centered in the display
  852. X *    Returns -1 on failure (0 for 0th button, 1 for 1st button, etc.)
  853. X */
  854. Xvoid
  855. XUseNoticeBoxSync(dpy,screen,noticeBox,callback)
  856. X    Display        *dpy;
  857. X    int        screen;
  858. X    NoticeBox    *noticeBox;
  859. X    void        (*callback)();
  860. X{
  861. X    noticeBoxDetails    *boxDetails;
  862. X
  863. X    boxDetails = CreateNoticeBox(dpy,screen,noticeBox,callback);
  864. X
  865. X    ShowNoticeBox(dpy,boxDetails);
  866. X}
  867. X
  868. X/*
  869. X * UseNoticeBox() -- NoticeBox with no callback
  870. X */
  871. Xint
  872. XUseNoticeBox( dpy, screen, noticeBox )
  873. XDisplay        *dpy;
  874. Xint        screen;
  875. XNoticeBox    *noticeBox;
  876. X{
  877. X    UseNoticeBoxSync(dpy,screen,noticeBox,NULL);
  878. X}
  879. X    
  880. END_OF_FILE
  881. if test 22967 -ne `wc -c <'Notice.c'`; then
  882.     echo shar: \"'Notice.c'\" unpacked with wrong size!
  883. fi
  884. # end of 'Notice.c'
  885. fi
  886. if test -f 'ol_button.c' -a "${1}" != "-c" ; then 
  887.   echo shar: Will not clobber existing file \"'ol_button.c'\"
  888. else
  889. echo shar: Extracting \"'ol_button.c'\" \(26874 characters\)
  890. sed "s/^X//" >'ol_button.c' <<'END_OF_FILE'
  891. X#ident "@(#)ol_button.c    1.1 olvwm version 1/3/92"
  892. X
  893. X/*
  894. X * Based on
  895. X#ident "@(#)ol_button.c    1.40 91/09/06 SMI"
  896. X *
  897. X */
  898. X
  899. X/*
  900. X * Copyright 1989-1990 Sun Microsystems  See LEGAL_NOTICE for terms of
  901. X * disclosure.
  902. X */
  903. X
  904. X/*
  905. X * OPEN LOOK object drawing package Sun Microsystems, Inc.
  906. X * 
  907. X * OLGX_button.c Menu button module
  908. X */
  909. X
  910. X#include <stdio.h>
  911. X#include <X11/Xlib.h>
  912. X#include <X11/Xutil.h>
  913. X#include "olgx_impl.h"
  914. X
  915. X#include "win.h"
  916. X#include "menu.h"
  917. X
  918. X/*
  919. X * Private function declarations
  920. X */
  921. X
  922. Xvoid            olgx_set_busy_stipple();
  923. Xvoid            olgx_draw_pixmap_label();
  924. X
  925. Xvoid
  926. Xolgx_draw_button(info, win, x, y, width, height, label, state)
  927. X    Graphics_info  *info;
  928. X    Window          win;
  929. X    int             x, y, width, height;
  930. X    void           *label;
  931. X    int             state;
  932. X{
  933. X    XTextItem       item;
  934. X    char            string[STRING_SIZE];
  935. X    short           add_ins[STRING_SIZE];
  936. X    register int    i;
  937. X    int             num_add;
  938. X    int             inside_width;    /* width minus endcaps */
  939. X    int             top_color, bottom_color, fill_color;
  940. X
  941. X
  942. X    inside_width = width - (2 * info->endcap_width);
  943. X    num_add = calc_add_ins(inside_width - 1, add_ins);
  944. X    item.nchars = 2 + num_add;
  945. X    item.font = None;
  946. X    item.chars = string;
  947. X    item.delta = 0;
  948. X
  949. X
  950. X    if (height)
  951. X    /* variable height button-- possibly a pixmap label */
  952. X
  953. X    olgx_draw_varheight_button(info, win, x, y, width, height, state);
  954. X
  955. X    else {
  956. X
  957. X    if (info->three_d) {
  958. X
  959. X        /*
  960. X         * 3d determine what colors we should draw in
  961. X         */
  962. X
  963. X        if (state & OLGX_INVOKED) {    /* invoked button */
  964. X        top_color = OLGX_BG3;
  965. X        bottom_color = OLGX_WHITE;
  966. X        fill_color = OLGX_BG2;
  967. X
  968. X        } else if ((state & OLGX_DEFAULT) && (state & OLGX_MENU_ITEM)) {
  969. X
  970. X                  /* default menu item */
  971. X        top_color = bottom_color = OLGX_BG3;
  972. X        fill_color = OLGX_BG1;
  973. X
  974. X        } else if (state & OLGX_MENU_ITEM && state & OLGX_BUSY) {
  975. X                  /* busy menu item */
  976. X
  977. X        fill_color = top_color = bottom_color = OLGX_BG1;
  978. X
  979. X        } else if (state & OLGX_MENU_ITEM) {    /* normal menu item */
  980. X
  981. X        fill_color = top_color = bottom_color = NONE;
  982. X
  983. X        } else {        /* normal panel button */
  984. X
  985. X        top_color = OLGX_WHITE;
  986. X        bottom_color = OLGX_BG3;
  987. X        fill_color = OLGX_BG1;
  988. X
  989. X        }
  990. X
  991. X        if (state & OLGX_BUSY) {
  992. X
  993. X        /*
  994. X         * This routine changes GC information on-the-fly, but it is
  995. X         * assumed that OLGX_BUSY won't be called often, so it makes
  996. X         * sense to use the same GC rather than one for ` each color.
  997. X         */
  998. X
  999. X        if (!info->gc_rec[OLGX_BUSYGC])
  1000. X            olgx_initialise_gcrec(info, OLGX_BUSYGC);
  1001. X        fill_color = OLGX_BUSYGC;
  1002. X
  1003. X        }
  1004. X        /* only check erase on transparent items */
  1005. X
  1006. X        if (fill_color == NONE) {
  1007. X
  1008. X        if (state & OLGX_ERASE) {
  1009. X
  1010. X            /*
  1011. X             * to improve performance, we erase a rectangle the size
  1012. X             * of a button rather than drawing a real button.
  1013. X             */
  1014. X
  1015. X           XFillRectangle(info->dpy, win, info->gc_rec[OLGX_BG1]->gc, 
  1016. X                                  x, y, width, Button_Height(info));
  1017. X        }
  1018. X        } else {        /* if not transparent, actually draw the
  1019. X                 * button */
  1020. X
  1021. X        if (top_color != NONE) {
  1022. X
  1023. X            /* draw the top part of the button */
  1024. X
  1025. X            string[0] = BUTTON_UL;
  1026. X            VARIABLE_LENGTH_MACRO(1, BUTTON_TOP_1);
  1027. X            string[i + 1] = BUTTON_UR;
  1028. X            XDrawText(info->dpy, win,
  1029. X                  info->gc_rec[top_color]->gc, x, y, &item, 1);
  1030. X
  1031. X        }
  1032. X        if (bottom_color != NONE) {
  1033. X
  1034. X            /* draw the bottom part of the button */
  1035. X
  1036. X            string[0] = BUTTON_LL;
  1037. X            VARIABLE_LENGTH_MACRO(1, BUTTON_BOTTOM_1);
  1038. X            string[i + 1] = BUTTON_LR;
  1039. X            XDrawText(info->dpy, win,
  1040. X                info->gc_rec[bottom_color]->gc, x, y, &item, 1);
  1041. X
  1042. X        }
  1043. X        /* Fill in the button */
  1044. X
  1045. X        string[0] = BUTTON_LEFT_ENDCAP_FILL;
  1046. X        VARIABLE_LENGTH_MACRO(1, BUTTON_FILL_1);
  1047. X        string[i + 1] = BUTTON_RIGHT_ENDCAP_FILL;
  1048. X        XDrawText(info->dpy, win,
  1049. X              info->gc_rec[fill_color]->gc, x, y, &item, 1);
  1050. X
  1051. X        /* draw the inner border of a default button (not menu item) */
  1052. X
  1053. X        if (!(state & OLGX_MENU_ITEM) && (state & OLGX_DEFAULT)) {
  1054. X            string[0] = DFLT_BUTTON_LEFT_ENDCAP;
  1055. X            VARIABLE_LENGTH_MACRO(1, DFLT_BUTTON_MIDDLE_1);
  1056. X            string[i + 1] = DFLT_BUTTON_RIGHT_ENDCAP;
  1057. X            XDrawText(info->dpy, win,
  1058. X                  info->gc_rec[OLGX_BG3]->gc, x, y, &item, 1);
  1059. X        }
  1060. X        }            /* Not transparent */
  1061. X
  1062. X    }
  1063. X    /* End 3D */
  1064. X    else {            /* draw 2d button */
  1065. X
  1066. X        if (state & OLGX_ERASE)
  1067. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x, y,
  1068. X                   width + 1, Button_Height(info));
  1069. X
  1070. X
  1071. X        if ((state & OLGX_INVOKED)) {
  1072. X        string[0] = BUTTON_FILL_2D_LEFTENDCAP;
  1073. X        VARIABLE_LENGTH_MACRO(1, BUTTON_FILL_2D_MIDDLE_1);
  1074. X        string[i + 1] = BUTTON_FILL_2D_RIGHTENDCAP;
  1075. X        XDrawText(info->dpy, win,
  1076. X              info->gc_rec[OLGX_BLACK]->gc, x, y, &item, 1);
  1077. X
  1078. X        } else if (state & OLGX_BUSY) {
  1079. X
  1080. X        if (!info->gc_rec[OLGX_BUSYGC])
  1081. X            olgx_initialise_gcrec(info, OLGX_BUSYGC);
  1082. X        string[0] = BUTTON_FILL_2D_LEFTENDCAP;
  1083. X        VARIABLE_LENGTH_MACRO(1, BUTTON_FILL_2D_MIDDLE_1);
  1084. X        string[i + 1] = BUTTON_FILL_2D_RIGHTENDCAP;
  1085. X        XDrawText(info->dpy, win,
  1086. X              info->gc_rec[OLGX_BUSYGC]->gc, x, y, &item, 1);
  1087. X
  1088. X        } else if (!(state & OLGX_MENU_ITEM) && (state & OLGX_DEFAULT)) {
  1089. X
  1090. X        /* draw the 2d default ring if not menu-item */
  1091. X
  1092. X        string[0] = DFLT_BUTTON_LEFT_ENDCAP;
  1093. X        VARIABLE_LENGTH_MACRO(1, DFLT_BUTTON_MIDDLE_1);
  1094. X        string[i + 1] = DFLT_BUTTON_RIGHT_ENDCAP;
  1095. X        XDrawText(info->dpy, win,
  1096. X              info->gc_rec[OLGX_BLACK]->gc, x, y, &item, 1);
  1097. X
  1098. X        } else if (state & OLGX_DEFAULT) {
  1099. X
  1100. X        /* draw the 2d default ring for menu item */
  1101. X
  1102. X        string[0] = MENU_DFLT_OUTLINE_LEFT_ENDCAP;
  1103. X        VARIABLE_LENGTH_MACRO(1, MENU_DFLT_OUTLINE_MIDDLE_1);
  1104. X        string[i + 1] = MENU_DFLT_OUTLINE_RIGHT_ENDCAP;
  1105. X        XDrawText(info->dpy, win,
  1106. X              info->gc_rec[OLGX_BLACK]->gc, x, y, &item, 1);
  1107. X
  1108. X        }
  1109. X        /* draw the button if it is not a menu item */
  1110. X
  1111. X        if (!(state & OLGX_MENU_ITEM)) {
  1112. X        string[0] = BUTTON_OUTLINE_LEFT_ENDCAP;
  1113. X        VARIABLE_LENGTH_MACRO(1, BUTTON_OUTLINE_MIDDLE_1);
  1114. X        string[i + 1] = BUTTON_OUTLINE_RIGHT_ENDCAP;
  1115. X        XDrawText(info->dpy, win,
  1116. X              info->gc_rec[OLGX_BLACK]->gc, x, y, &item, 1);
  1117. X        }
  1118. X    }
  1119. X    }
  1120. X
  1121. X    /*
  1122. X     * Place the label, if specified.
  1123. X     */
  1124. X
  1125. X    if (label) {
  1126. X
  1127. X    if (state & OLGX_LABEL_IS_PIXMAP) {
  1128. X
  1129. X        int             centerx, centery;
  1130. X
  1131. X        centerx = (width - ((Pixlabel *) label)->width >> 1);
  1132. X        centery = (height - ((Pixlabel *) label)->height >> 1);
  1133. X        olgx_draw_pixmap_label(info, win,
  1134. X                   ((Pixlabel *) label)->pixmap,
  1135. X                   x + ((centerx > 0) ? centerx : 0),
  1136. X                   y + ((centery > 0) ? centery : 0),
  1137. X                   ((Pixlabel *) label)->width,
  1138. X                  (height) ? height : Button_Height(info) - 2, state);
  1139. X    } else if (state & OLGX_LABEL_IS_COMB) {
  1140. X        Comblabel    *combLabel;
  1141. X        int        centery;
  1142. X
  1143. X        combLabel = (Comblabel *) label;
  1144. X        centery = (((height) ? height : Button_Height(info) - 2) -
  1145. X            combLabel->pixlabel.height) >> 1;
  1146. X        olgx_draw_pixmap_label(info, win, combLabel->pixlabel.pixmap,
  1147. X                x + info->endcap_width,
  1148. X                y + ((centery > 0) ? centery : 0),
  1149. X                combLabel->pixlabel.width,
  1150. X                (height) ? combLabel->pixlabel.height :
  1151. X                       Button_Height(info) - 2, state);
  1152. X#ifdef OW_I18N
  1153. X        olgx_draw_text(info, win, (wchar_t *) combLabel->strlabel,
  1154. X#else
  1155. X        olgx_draw_text(info, win, (char *) combLabel->strlabel,
  1156. X#endif
  1157. X            x + info->endcap_width + combLabel->pixlabel.width + 5,
  1158. X            y + info->button_height - info->base_off,
  1159. X            inside_width - combLabel->pixlabel.width -
  1160. X                ((state & OLGX_MENU_MARK) ? info->mm_width : 0),
  1161. X            state);
  1162. X    } else {
  1163. X
  1164. X#ifdef OW_I18N
  1165. X        /*
  1166. X         * FIX_ME: Binary compat. Need some flag to tell char or
  1167. X         * wchar_t.
  1168. X         */
  1169. X        olgx_draw_text(info, win, (wchar_t *) label,
  1170. X#else
  1171. X        olgx_draw_text(info, win, (char *) label,
  1172. X#endif /* OW_I18N */
  1173. X               x + info->endcap_width,
  1174. X               y + info->button_height - info->base_off,
  1175. X               inside_width -
  1176. X               ((state & OLGX_MENU_MARK) ?
  1177. X                info->mm_width : 0),
  1178. X               state);
  1179. X    }
  1180. X    }
  1181. X    /*
  1182. X     * Place the menu mark, if desired.
  1183. X     */
  1184. X
  1185. X    if (state & OLGX_MENU_MARK) {
  1186. X
  1187. X    /*
  1188. X     * draw the menu mark. (fill_color != OLGX_BG2) causes the menu mark
  1189. X     * to be filled in only when necessary
  1190. X     */
  1191. X
  1192. X    if (info->three_d)
  1193. X        olgx_draw_menu_mark(info, win,
  1194. X              x + (width - info->endcap_width - info->mm_width),
  1195. X                y + (info->button_height - info->mm_height -
  1196. X                     info->base_off),
  1197. X                state, (fill_color != OLGX_BG2));
  1198. X    else
  1199. X        olgx_draw_menu_mark(info, win,
  1200. X              x + (width - info->endcap_width - info->mm_width),
  1201. X                y + (info->button_height - info->mm_height -
  1202. X                     info->base_off),
  1203. X                state, 0);
  1204. X    }
  1205. X    /*
  1206. X     * Mark the item as inactive, if specified
  1207. X     */
  1208. X
  1209. X    if (state & OLGX_INACTIVE) {
  1210. X    olgx_stipple_rect(info, win, x, y, width, 
  1211. X                          (height) ? height + 8 : Button_Height(info));
  1212. X
  1213. X    }
  1214. X}
  1215. X
  1216. X
  1217. X/*
  1218. X * Draw the outline of a variable height button Private Routine
  1219. X */
  1220. X
  1221. Xvoid
  1222. Xolgx_draw_varheight_button(info, win, x, y, width, height, state)
  1223. X    Graphics_info  *info;
  1224. X    Window          win;
  1225. X    int             x, y, width, height;
  1226. X    int             state;
  1227. X
  1228. X{
  1229. X
  1230. X
  1231. X    char            string[2];
  1232. X    XSegment        seg[4];
  1233. X
  1234. X
  1235. X    if (info->three_d) {
  1236. X
  1237. X    /* 3D */
  1238. X    /* Draw all the four corners */
  1239. X
  1240. X    if (state & OLGX_INVOKED)
  1241. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_BG2]->gc, x + 1,
  1242. X               y + 1, width - 2, height - 2);
  1243. X    else
  1244. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_BG1]->gc, x + 1,
  1245. X               y + 1, width - 2, height - 2);
  1246. X
  1247. X    string[0] = PIXLABEL_BUTTON_UL;
  1248. X    XDrawString(info->dpy, win, (state & OLGX_INVOKED) ?
  1249. X        info->gc_rec[OLGX_BG3]->gc : info->gc_rec[OLGX_WHITE]->gc, x, y,
  1250. X            string, 1);
  1251. X
  1252. X    string[0] = PIXLABEL_BUTTON_UR;
  1253. X    XDrawString(info->dpy, win, (state & OLGX_INVOKED) ?
  1254. X          info->gc_rec[OLGX_BG3]->gc : info->gc_rec[OLGX_WHITE]->gc,
  1255. X            x + width - VARHEIGHT_BUTTON_CORNER_DIMEN, y, string, 1);
  1256. X
  1257. X    string[0] = PIXLABEL_BUTTON_LL;
  1258. X    XDrawString(info->dpy, win, (state & OLGX_INVOKED) ?
  1259. X       info->gc_rec[OLGX_WHITE]->gc : info->gc_rec[OLGX_BG3]->gc, x, y +
  1260. X            height - VARHEIGHT_BUTTON_CORNER_DIMEN, string, 1);
  1261. X
  1262. X    string[0] = PIXLABEL_BUTTON_LR;
  1263. X    XDrawString(info->dpy, win, (state & OLGX_INVOKED) ?
  1264. X          info->gc_rec[OLGX_WHITE]->gc : info->gc_rec[OLGX_BG3]->gc,
  1265. X            x + width - VARHEIGHT_BUTTON_CORNER_DIMEN,
  1266. X            y + height - VARHEIGHT_BUTTON_CORNER_DIMEN, string, 1);
  1267. X
  1268. X    seg[0].x1 = x + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1269. X    seg[0].y1 = seg[0].y2 = y;
  1270. X    seg[0].x2 = x + width - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1271. X    seg[1].x1 = seg[1].x2 = x;
  1272. X    seg[1].y1 = y + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1273. X    seg[1].y2 = y + height - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1274. X    XDrawSegments(info->dpy, win, (state & OLGX_INVOKED) ? 
  1275. X                                        info->gc_rec[OLGX_BG3]->gc :
  1276. X                                info->gc_rec[OLGX_WHITE]->gc,
  1277. X                     seg, 2);
  1278. X    seg[0].x1 = x + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1279. X    seg[0].y1 = seg[0].y2 = y + height - 1;
  1280. X    seg[0].x2 = x + width - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1281. X    seg[1].x1 = seg[1].x2 = x + width - 1;
  1282. X    seg[1].y1 = y + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1283. X    seg[1].y2 = y + height - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1284. X    XDrawSegments(info->dpy, win, (state & OLGX_INVOKED) ? 
  1285. X                                        info->gc_rec[OLGX_WHITE]->gc :
  1286. X                                info->gc_rec[OLGX_BG3]->gc,
  1287. X                      seg, 2);
  1288. X
  1289. X
  1290. X    } else {
  1291. X
  1292. X    /* 2D */
  1293. X
  1294. X    if (state & OLGX_INVOKED)
  1295. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x + 3,
  1296. X               y + 3, width - 6, height - 6);
  1297. X    else
  1298. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x + 1,
  1299. X               y + 1, width - 2, height - 2);
  1300. X
  1301. X    string[0] = PIXLABEL_BUTTON_UL;
  1302. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y, string, 1);
  1303. X    string[0] = PIXLABEL_BUTTON_UR;
  1304. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc,
  1305. X            x + width - VARHEIGHT_BUTTON_CORNER_DIMEN, y, string, 1);
  1306. X
  1307. X    string[0] = PIXLABEL_BUTTON_LL;
  1308. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x,
  1309. X            y + height - VARHEIGHT_BUTTON_CORNER_DIMEN, string, 1);
  1310. X
  1311. X    string[0] = PIXLABEL_BUTTON_LR;
  1312. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc,
  1313. X            x + width - VARHEIGHT_BUTTON_CORNER_DIMEN,
  1314. X            y + height - VARHEIGHT_BUTTON_CORNER_DIMEN, string, 1);
  1315. X
  1316. X    seg[0].x1 = x + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1317. X    seg[0].y1 = seg[0].y2 = y;
  1318. X    seg[0].x2 = x + width - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1319. X    seg[1].x1 = seg[1].x2 = x;
  1320. X    seg[1].y1 = y + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1321. X    seg[1].y2 = y + height - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1322. X    seg[2].x1 = x + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1323. X    seg[2].y1 = seg[2].y2 = y + height - 1;
  1324. X    seg[2].x2 = x + width - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1325. X    seg[3].x1 = seg[3].x2 = x + width - 1;
  1326. X    seg[3].y1 = y + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1327. X    seg[3].y2 = y + height - VARHEIGHT_BUTTON_CORNER_DIMEN;
  1328. X    XDrawSegments(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, seg, 4);
  1329. X
  1330. X    }
  1331. X
  1332. X    /*
  1333. X     * REMIND: the code below probably uses OLGX_BLACK incorrectly.  It should 
  1334. X     * be changed to use OLGX_BG3 in 3D mode as appropriate.
  1335. X     */
  1336. X
  1337. X    if (state & OLGX_DEFAULT) {
  1338. X
  1339. X    string[0] = PIXLABEL_DEF_BUTTON_UL;
  1340. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y,
  1341. X            string, 1);
  1342. X
  1343. X    string[0] = PIXLABEL_DEF_BUTTON_UR;
  1344. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x + width -
  1345. X            VARHEIGHT_BUTTON_CORNER_DIMEN, y, string, 1);
  1346. X
  1347. X    string[0] = PIXLABEL_DEF_BUTTON_LL;
  1348. X    XDrawString(info->dpy, win,
  1349. X            info->gc_rec[OLGX_BLACK]->gc, x, y + height -
  1350. X            VARHEIGHT_BUTTON_CORNER_DIMEN, string, 1);
  1351. X
  1352. X    string[0] = PIXLABEL_DEF_BUTTON_LR;
  1353. X    XDrawString(info->dpy, win,
  1354. X            info->gc_rec[OLGX_BLACK]->gc, x + width -
  1355. X            VARHEIGHT_BUTTON_CORNER_DIMEN, y + height -
  1356. X            VARHEIGHT_BUTTON_CORNER_DIMEN, string, 1);
  1357. X
  1358. X    seg[0].x1 = x + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1359. X    seg[0].y1 = seg[0].y2 = y + 2;
  1360. X    seg[0].x2 = x + width - VARHEIGHT_BUTTON_CORNER_DIMEN - 1;
  1361. X    seg[1].x1 = seg[1].x2 = x + 2;
  1362. X    seg[1].y1 = y + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1363. X    seg[1].y2 = y + height - VARHEIGHT_BUTTON_CORNER_DIMEN - 1;
  1364. X    seg[2].x1 = x + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1365. X    seg[2].y1 = seg[2].y2 = y + height - 1 - 2;
  1366. X    seg[2].x2 = x + width - VARHEIGHT_BUTTON_CORNER_DIMEN - 1;
  1367. X    seg[3].x1 = seg[3].x2 = x + width - 1 - 2;
  1368. X    seg[3].y1 = y + VARHEIGHT_BUTTON_CORNER_DIMEN;
  1369. X    seg[3].y2 = y + height - VARHEIGHT_BUTTON_CORNER_DIMEN - 1;
  1370. X    XDrawSegments(info->dpy, win,
  1371. X              info->gc_rec[OLGX_BLACK]->gc, seg, 4);
  1372. X
  1373. X    }
  1374. X    if (state & OLGX_BUSY) {
  1375. X
  1376. X    if (!info->gc_rec[OLGX_BUSYGC])
  1377. X        olgx_initialise_gcrec(info, OLGX_BUSYGC);
  1378. X
  1379. X    XFillRectangle(info->dpy, win, info->gc_rec[OLGX_BUSYGC]->gc, x + 2,
  1380. X               y + 2, width - 4, height - 4);
  1381. X    }
  1382. X}
  1383. X
  1384. X
  1385. Xvoid
  1386. Xolgx_draw_menu_mark(info, win, x, y, state, fill_in)
  1387. X    Graphics_info  *info;
  1388. X    Window          win;
  1389. X    int             state, fill_in;
  1390. X{
  1391. X    char            string[3];
  1392. X
  1393. X    if (state & OLGX_VERT_MENU_MARK)
  1394. X    string[0] = VERT_MENU_MARK_UL;
  1395. X    else if (state & OLGX_HORIZ_MENU_MARK)
  1396. X    string[0] = HORIZ_MENU_MARK_UL;
  1397. X    else if (state & OLGX_HORIZ_BACK_MENU_MARK)
  1398. X    string[0] = HORIZ_BACK_MENU_MARK_UL;
  1399. X    else if (state & OLGX_VERT_BACK_MENU_MARK)
  1400. X    string[0] = VERT_BACK_MENU_MARK_UL;
  1401. X
  1402. X    string[1] = string[0] + 1;
  1403. X
  1404. X    if ((state & OLGX_INVOKED) && (!info->three_d))
  1405. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x, y, &string[0],
  1406. X            info->three_d ? 1 : 2);
  1407. X    else
  1408. X    XDrawString(info->dpy, win, info->three_d ? info->gc_rec[OLGX_BG3]->gc :
  1409. X                                info->gc_rec[OLGX_BLACK]->gc,
  1410. X                    x, y, &string[0], info->three_d ? 1 : 2);
  1411. X
  1412. X    if (info->three_d)
  1413. X       XDrawString(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x, y, &string[1], 1);
  1414. X
  1415. X    /* fill in the menu mark, if requested */
  1416. X
  1417. X    if (fill_in) {
  1418. X    string[0] = string[0] + 2;
  1419. X    XDrawString(info->dpy, win, (info->three_d)?info->gc_rec[OLGX_BG2]->gc :
  1420. X                                            info->gc_rec[OLGX_BLACK]->gc,
  1421. X            x, y, &string[0], 1);
  1422. X
  1423. X    }
  1424. X}
  1425. X
  1426. X
  1427. X
  1428. X
  1429. Xvoid
  1430. Xolgx_draw_abbrev_button(info, win, x, y, state)
  1431. X    Graphics_info  *info;
  1432. X    Window          win;
  1433. X    int             x, y;
  1434. X    int             state;
  1435. X{
  1436. X    XTextItem       item;
  1437. X    char            string[3];
  1438. X    int             top_color, bottom_color, fill_color;
  1439. X
  1440. X    item.nchars = 1;
  1441. X    item.font = None;
  1442. X    item.chars = string;
  1443. X    item.delta = 0;
  1444. X
  1445. X
  1446. X    if (!info->three_d) {    /* 2d */
  1447. X
  1448. X    if (state & OLGX_ERASE)
  1449. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x, y,
  1450. X          Abbrev_MenuButton_Width(info), Abbrev_MenuButton_Width(info));
  1451. X
  1452. X    if (state & OLGX_BUSY) {
  1453. X
  1454. X        if (!info->gc_rec[OLGX_BUSYGC])
  1455. X        olgx_initialise_gcrec(info, OLGX_BUSYGC);
  1456. X        string[0] = ABBREV_MENU_FILL;
  1457. X        XDrawText(info->dpy, win, info->gc_rec[OLGX_BUSYGC]->gc, x, y, &item, 1);
  1458. X    }
  1459. X    if (state & OLGX_INVOKED) {
  1460. X
  1461. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x + 2, y + 2,
  1462. X               (Abbrev_MenuButton_Width(info) - 4), 
  1463. X                           (Abbrev_MenuButton_Width(info) - 4));
  1464. X        string[0] = OLG_ABBREV_MENU_BUTTON_INVERTED;
  1465. X        XDrawText(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y, &item, 1);
  1466. X
  1467. X    } else {
  1468. X
  1469. X        string[0] = OLG_ABBREV_MENU_BUTTON;
  1470. X        XDrawText(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y, &item, 1);
  1471. X
  1472. X    }
  1473. X
  1474. X    } else {            /* 3d */
  1475. X
  1476. X    if (state & OLGX_INVOKED) {
  1477. X
  1478. X        top_color = OLGX_BG3;
  1479. X        bottom_color = OLGX_WHITE;
  1480. X        fill_color = OLGX_BG2;
  1481. X
  1482. X    } else {
  1483. X
  1484. X        top_color = OLGX_WHITE;
  1485. X        bottom_color = OLGX_BG3;
  1486. X        fill_color = OLGX_BG1;
  1487. X
  1488. X    }
  1489. X
  1490. X    if (state & OLGX_BUSY) {
  1491. X
  1492. X        if (!info->gc_rec[OLGX_BUSYGC])
  1493. X        olgx_initialise_gcrec(info, OLGX_BUSYGC);
  1494. X        fill_color = OLGX_BUSYGC;
  1495. X
  1496. X    }
  1497. X    string[0] = ABBREV_MENU_UL;
  1498. X    XDrawText(info->dpy, win, info->gc_rec[top_color]->gc, x, y, &item, 1);
  1499. X
  1500. X    string[0] = ABBREV_MENU_LR;
  1501. X    XDrawText(info->dpy, win, info->gc_rec[bottom_color]->gc, x, y, &item, 1);
  1502. X
  1503. X    string[0] = ABBREV_MENU_FILL;
  1504. X    XDrawText(info->dpy, win, info->gc_rec[fill_color]->gc, x, y, &item, 1);
  1505. X    olgx_draw_menu_mark(info, win, x + ((Abbrev_MenuButton_Width(info)
  1506. X                         - info->mm_width) >> 1),
  1507. X                y + ((1 + Abbrev_MenuButton_Height(info) -
  1508. X                  info->mm_height) >> 1),
  1509. X                OLGX_VERT_MENU_MARK, 1);
  1510. X
  1511. X    }
  1512. X
  1513. X    /* If it is inactive fill the rectangle with inactive pixmap */
  1514. X
  1515. X    if (state & OLGX_INACTIVE) {
  1516. X
  1517. X    olgx_stipple_rect(info, win, x, y, Abbrev_MenuButton_Width(info),
  1518. X              Abbrev_MenuButton_Height(info));
  1519. X    }
  1520. X}
  1521. X
  1522. X
  1523. Xvoid
  1524. Xolgx_stipple_rect(info, win, x, y, width, height)
  1525. X    Graphics_info  *info;
  1526. X    Window          win;
  1527. X    int             x, y, width, height;
  1528. X{
  1529. X
  1530. X
  1531. X    if (!info->gc_rec[OLGX_GREY_OUT])
  1532. X    olgx_initialise_gcrec(info, OLGX_GREY_OUT);
  1533. X
  1534. X    XFillRectangle(info->dpy, win, info->gc_rec[OLGX_GREY_OUT]->gc,
  1535. X           x, y, width, height);
  1536. X}
  1537. X
  1538. Xvoid
  1539. Xolgx_draw_text(info, win, string, x, y, max_width, state)
  1540. X    Graphics_info  *info;
  1541. X    Window          win;
  1542. X#ifdef OW_I18N
  1543. X    wchar_t        *string;
  1544. X#else
  1545. X    char           *string;
  1546. X#endif /* OW_I18N */
  1547. X    int             x, y, max_width;
  1548. X    int             state;
  1549. X{
  1550. X
  1551. X#ifdef OW_I18N
  1552. X    int             len = wslen(string);
  1553. X#else
  1554. X    int             len = strlen(string);
  1555. X#endif /* OW_I18N */
  1556. X    register int    i;
  1557. X    short           more_flag = 0;
  1558. X
  1559. X
  1560. X    /*
  1561. X     * if the string is too long, we'll have to truncate it max_width == 0
  1562. X     * implies don't truncate.
  1563. X     */
  1564. X
  1565. X#ifdef OW_I18N
  1566. X    if (max_width && XwcTextEscapement(info->textfontset,
  1567. X                        string, len) > max_width) {
  1568. X#else
  1569. X    if (max_width && XTextWidth(info->textfont, string, len) > max_width) {
  1570. X#endif /* OW_I18N */
  1571. X       int             current_width = 0;        
  1572. X       for (i = 0; (i < len && current_width <= max_width); i++) {
  1573. X#ifdef OW_I18N
  1574. X       current_width +=
  1575. X        XwcTextEscapement(info->textfontset, &string[i], 1);
  1576. X#else
  1577. X           current_width += XTextWidth(info->textfont, &string[i], 1);
  1578. X#endif /* OW_I18N */
  1579. X    }    
  1580. X
  1581. X    /*
  1582. X     * at this point, i-1 represents the number of chars of string that
  1583. X     * will fit into max_width.
  1584. X     */
  1585. X
  1586. X    len = i - 2;
  1587. X    if (state & OLGX_MORE_ARROW) 
  1588. X           more_flag = 1;
  1589. X    }    
  1590. X    if (!info->gc_rec[OLGX_TEXTGC])
  1591. X    olgx_initialise_gcrec(info, OLGX_TEXTGC);
  1592. X    if (!info->three_d)
  1593. X      if (!info->gc_rec[OLGX_TEXTGC_REV])
  1594. X        olgx_initialise_gcrec(info, OLGX_TEXTGC_REV);
  1595. X
  1596. X    if ((state & OLGX_INVOKED) && !(info->three_d))
  1597. X#ifdef OW_I18N
  1598. X      XwcDrawString(info->dpy, win, info->textfontset,
  1599. X                  info->gc_rec[OLGX_TEXTGC_REV]->gc, x, y, string, len);
  1600. X    else
  1601. X      XwcDrawString(info->dpy, win, info->textfontset,
  1602. X                  info->gc_rec[OLGX_TEXTGC]->gc, x, y, string, len);
  1603. X#else OW_I18N
  1604. X      XDrawString(info->dpy, win, info->gc_rec[OLGX_TEXTGC_REV]->gc, x, y, 
  1605. X                  string, len);
  1606. X    else
  1607. X      XDrawString(info->dpy, win, info->gc_rec[OLGX_TEXTGC]->gc, x, y, string, len);
  1608. X#endif /* OW_I18N */
  1609. X
  1610. X    if (more_flag) /* render a more arrow at the end of the string */ 
  1611. X#ifdef OW_I18N
  1612. X       olgx_draw_menu_mark(info,win,
  1613. X               x+XwcTextEscapement(info->textfontset,string,len)+1,
  1614. X#else
  1615. X       olgx_draw_menu_mark(info,win,x+XTextWidth(info->textfont,string,len)+1 ,
  1616. X#endif /* OW_I18N */
  1617. X               y-MenuMark_Height(info),OLGX_HORIZ_MENU_MARK,1);
  1618. X}
  1619. X
  1620. Xvoid
  1621. Xolgx_draw_pixmap_label(info, win, pix, x, y, width, height, state)
  1622. X    Graphics_info  *info;
  1623. X    Window          win;
  1624. X    Pixmap          pix;
  1625. X    int             x, y, width, height, state;
  1626. X{
  1627. X
  1628. X
  1629. X    unsigned long       savebg1;
  1630. X    unsigned long       savebg2;
  1631. X    Window              root;
  1632. X    int                 x_dummy,y_dummy;
  1633. X    unsigned int        w_dummy,h_dummy,bw_dummy;
  1634. X    unsigned int        depth;
  1635. X    GC            gc;
  1636. X        
  1637. X
  1638. X    if (!info->gc_rec[OLGX_TEXTGC])
  1639. X    olgx_initialise_gcrec(info, OLGX_TEXTGC);
  1640. X    if (!info->three_d)
  1641. X      if (!info->gc_rec[OLGX_TEXTGC_REV])
  1642. X        olgx_initialise_gcrec(info, OLGX_TEXTGC_REV);
  1643. X
  1644. X    if ((state & OLGX_INVOKED)) {
  1645. X    if (info->three_d) {
  1646. X        /*
  1647. X         * reset the value of the textgc background from bg1 to bg2 in
  1648. X         * invoked mode to get the transparent pixmap effect
  1649. X         */
  1650. X        savebg1 = olgx_get_single_color(info, OLGX_BG1);
  1651. X        savebg2 = olgx_get_single_color(info, OLGX_BG2);
  1652. X        olgx_set_single_color(info, OLGX_BG1, savebg2, OLGX_SPECIAL);
  1653. X        gc = info->gc_rec[OLGX_TEXTGC]->gc;
  1654. X    }
  1655. X    else {
  1656. X        if (!info->gc_rec[OLGX_TEXTGC_REV])
  1657. X        olgx_initialise_gcrec(info, OLGX_TEXTGC_REV);
  1658. X        gc = info->gc_rec[OLGX_TEXTGC_REV]->gc;
  1659. X    }
  1660. X    }
  1661. X    else gc = info->gc_rec[OLGX_TEXTGC]->gc;
  1662. X
  1663. X    /*
  1664. X     * Performance Problem - RoundTrip request
  1665. X     * Depth should be passed as part of Pixlabel struct
  1666. X     */
  1667. X
  1668. X    XGetGeometry(info->dpy,pix,&root,&x_dummy,&y_dummy,&w_dummy,
  1669. X                 &h_dummy,&bw_dummy,&depth);
  1670. X    if (depth > 1) 
  1671. X        XCopyArea(info->dpy,
  1672. X                     pix,        /* src */
  1673. X              win,        /* dest */
  1674. X          gc,
  1675. X              0, 0,        /* src x,y */
  1676. X              width, height,
  1677. X              x, y);
  1678. X    else 
  1679. X        XCopyPlane(info->dpy,
  1680. X                     pix,        /* src */
  1681. X              win,        /* dest */
  1682. X          gc,
  1683. X              0, 0,        /* src x,y */
  1684. X              width, height,
  1685. X              x, y,
  1686. X                  (unsigned long) 1);
  1687. X       
  1688. X
  1689. X    /* Restore the original colors to the textgc  */
  1690. X
  1691. X    if ((state & OLGX_INVOKED) && (info->three_d))
  1692. X    olgx_set_single_color(info, OLGX_BG1, savebg1, OLGX_SPECIAL);
  1693. X
  1694. X}
  1695. X
  1696. X
  1697. X
  1698. Xvoid
  1699. Xolgx_draw_textscroll_button(info, win, x, y, state)
  1700. X    Graphics_info  *info;
  1701. X    Window          win;
  1702. X    int             x, y;
  1703. X    int             state;
  1704. X
  1705. X{
  1706. X    char            string[2];
  1707. X    int             width, height;
  1708. X    int             arr_x, arr_y;
  1709. X
  1710. X    /*
  1711. X     * A small hack to calculate the width, arrow postiton..etc since this
  1712. X     * routine is expected to tbe used infrequently it is not included as
  1713. X     * part of the info struct and the follwoing calculations take place each
  1714. X     * time-- a penalty affordable at the cost of infrequency
  1715. X     * 
  1716. X     */
  1717. X
  1718. X    if ((Abbrev_MenuButton_Height(info)) < 20) {
  1719. X
  1720. X    width = height = Abbrev_MenuButton_Height(info);
  1721. X
  1722. X    arr_y = 3;
  1723. X    arr_x = (width / 3) - 1;
  1724. X
  1725. X    } else {
  1726. X
  1727. X    width = height = 25;    /* Special case size-19 */
  1728. X    arr_y = 5;
  1729. X    arr_x = 7;
  1730. X
  1731. X    }
  1732. X
  1733. X
  1734. X    if (!(info->three_d)) {    /* Start 2-D */
  1735. X
  1736. X    if (state & OLGX_ERASE)
  1737. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x, y, width,
  1738. X                           height);
  1739. X
  1740. X    if (state & OLGX_SCROLL_FORWARD) {
  1741. X
  1742. X        if (state & OLGX_INVOKED)
  1743. X        string[0] = TEXTSCROLLBUTTON_RIGHT_INV;
  1744. X        else
  1745. X        string[0] = TEXTSCROLLBUTTON_RIGHT;
  1746. X
  1747. X        XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y, string,1);
  1748. X
  1749. X    } else if (state & OLGX_SCROLL_BACKWARD) {
  1750. X
  1751. X        if (state & OLGX_INVOKED)
  1752. X        string[0] = TEXTSCROLLBUTTON_LEFT_INV;
  1753. X        else
  1754. X        string[0] = TEXTSCROLLBUTTON_LEFT;
  1755. X        XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y, string,1);
  1756. X    }
  1757. X    }
  1758. X    /* End 2-D */
  1759. X    else {            /* Start 3-D */
  1760. X
  1761. X    olgx_draw_box(info, win, x, y, width, height, state, 0);
  1762. X
  1763. X    if (state & OLGX_SCROLL_FORWARD)
  1764. X        olgx_draw_menu_mark(info, win, x + arr_x, y + arr_y,
  1765. X                OLGX_HORIZ_MENU_MARK | OLGX_INVOKED, 1);
  1766. X    else
  1767. X        olgx_draw_menu_mark(info, win, x + arr_x - 1, y + arr_y,
  1768. X                OLGX_HORIZ_BACK_MENU_MARK | OLGX_INVOKED, 1);
  1769. X
  1770. X    }                /* End 3-D */
  1771. X
  1772. X    if (state & OLGX_INACTIVE)
  1773. X    olgx_stipple_rect(info, win, x, y, TextScrollButton_Width(info),
  1774. X              TextScrollButton_Height(info));
  1775. X
  1776. X}
  1777. X
  1778. X
  1779. X
  1780. X
  1781. X
  1782. X
  1783. Xvoid
  1784. Xolgx_draw_numscroll_button(info, win, x, y, state)
  1785. X    Graphics_info  *info;
  1786. X    Window          win;
  1787. X    int             x, y, state;
  1788. X
  1789. X{
  1790. X
  1791. X    char            string[2];
  1792. X    int             width, height, arr_x, arr_y;
  1793. X
  1794. X    width = height = TextScrollButton_Height(info);
  1795. X
  1796. X    if (width < 20) {
  1797. X
  1798. X    arr_y = 3;
  1799. X    arr_x = (width / 3) - 1;
  1800. X
  1801. X    } else {
  1802. X
  1803. X    arr_y = 5;
  1804. X    arr_x = 7;
  1805. X
  1806. X    }
  1807. X
  1808. X
  1809. X    if (!info->three_d) {    /* draw 2-D */
  1810. X
  1811. X    if (state & OLGX_ERASE)
  1812. X        XFillRectangle(info->dpy, win, info->gc_rec[OLGX_WHITE]->gc, x, y,
  1813. X                           NumScrollButton_Width(info), height);
  1814. X
  1815. X    if (state & OLGX_SCROLL_FORWARD)
  1816. X        string[0] = NUMERIC_SCROLL_BUTTON_RIGHT_INV;
  1817. X
  1818. X    else if (state & OLGX_SCROLL_BACKWARD)
  1819. X        string[0] = NUMERIC_SCROLL_BUTTON_LEFT_INV;
  1820. X
  1821. X    else
  1822. X        string[0] = NUMERIC_SCROLL_BUTTON_NORMAL;
  1823. X
  1824. X    XDrawString(info->dpy, win, info->gc_rec[OLGX_BLACK]->gc, x, y, string, 1);
  1825. X
  1826. X    } else {            /* draw 3-D */
  1827. X
  1828. X    olgx_draw_box(info, win, x, y, width, height,
  1829. X                      (state & OLGX_SCROLL_BACKWARD) ?
  1830. X               OLGX_INVOKED : OLGX_NORMAL, 0);
  1831. X    olgx_draw_box(info, win, x + width, y, width, height,
  1832. X              (state & OLGX_SCROLL_FORWARD) ?
  1833. X              OLGX_INVOKED : OLGX_NORMAL, 0);
  1834. X    olgx_draw_menu_mark(info, win, x + arr_x, y + arr_y,
  1835. X                OLGX_VERT_BACK_MENU_MARK | OLGX_INVOKED, 1);
  1836. X    olgx_draw_menu_mark(info, win, x + arr_x + width, y + arr_y,
  1837. X                OLGX_VERT_MENU_MARK | OLGX_INVOKED, 1);
  1838. X
  1839. X    }
  1840. X
  1841. X    if (state & OLGX_INACTIVE)
  1842. X    olgx_stipple_rect(info, win, x, y, NumScrollButton_Width(info),
  1843. X              NumScrollButton_Height(info));
  1844. X
  1845. X    if (state & OLGX_SCROLL_NO_FORWARD)
  1846. X    olgx_stipple_rect(info, win, x + TextScrollButton_Width(info) - 1, y,
  1847. X              TextScrollButton_Width(info),
  1848. X              NumScrollButton_Height(info));
  1849. X
  1850. X    if (state & OLGX_SCROLL_NO_BACKWARD)
  1851. X    olgx_stipple_rect(info, win, x, y,
  1852. X              TextScrollButton_Width(info) - 2,
  1853. X              NumScrollButton_Height(info));
  1854. X}
  1855. X
  1856. X
  1857. X
  1858. X
  1859. X
  1860. END_OF_FILE
  1861. if test 26874 -ne `wc -c <'ol_button.c'`; then
  1862.     echo shar: \"'ol_button.c'\" unpacked with wrong size!
  1863. fi
  1864. # end of 'ol_button.c'
  1865. fi
  1866. if test -f 'vdm.icon' -a "${1}" != "-c" ; then 
  1867.   echo shar: Will not clobber existing file \"'vdm.icon'\"
  1868. else
  1869. echo shar: Extracting \"'vdm.icon'\" \(1919 characters\)
  1870. sed "s/^X//" >'vdm.icon' <<'END_OF_FILE'
  1871. X#define vdm_width 64
  1872. X#define vdm_height 45
  1873. Xstatic char vdm_bits[] = {
  1874. X 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
  1875. X 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,
  1876. X 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,
  1877. X 0x71,0x00,0x00,0x00,0x00,0x00,0xc0,0xe1,0x86,0x01,0x00,0x00,0x00,0x00,0x38,
  1878. X 0x1c,0x38,0x0e,0x00,0x00,0x00,0x00,0x07,0x03,0xc0,0x30,0x00,0x00,0x00,0xe0,
  1879. X 0x70,0x1c,0x00,0xc7,0x01,0x00,0x00,0x1c,0x8e,0x61,0x00,0x18,0x06,0x00,0x80,
  1880. X 0xc3,0x01,0x8e,0x03,0x07,0x18,0x00,0x70,0x20,0x00,0x10,0xec,0x00,0x17,0x00,
  1881. X 0x0e,0x20,0x1c,0x10,0x10,0xe0,0x18,0xc0,0x01,0xc0,0x63,0x0e,0x00,0x1c,0x17,
  1882. X 0x30,0x00,0x30,0x80,0x03,0x80,0xe3,0x10,0xd0,0x00,0x08,0x00,0x04,0x70,0x1c,
  1883. X 0x10,0x10,0x07,0x08,0x00,0x04,0x8e,0x03,0x10,0x10,0x18,0x70,0x80,0xc3,0x71,
  1884. X 0x01,0x10,0x10,0xe0,0x80,0x71,0x38,0x0e,0x01,0x18,0x10,0x00,0x03,0x0e,0xc7,
  1885. X 0x01,0x01,0x17,0x10,0x00,0x1c,0xe0,0x38,0x00,0xe1,0x10,0x10,0x06,0x60,0x1c,
  1886. X 0x07,0x00,0x1d,0x10,0x10,0x06,0x80,0xe3,0x00,0x00,0x03,0x10,0x10,0x06,0x00,
  1887. X 0x1d,0x00,0x00,0x01,0x10,0x10,0x04,0x06,0x13,0x00,0x00,0x01,0x18,0x10,0x0c,
  1888. X 0x06,0x11,0x00,0x00,0x01,0x17,0x10,0x0c,0x06,0x39,0x00,0x00,0xe1,0x10,0x10,
  1889. X 0x08,0x02,0xc7,0x00,0x00,0x1d,0x10,0x10,0x18,0x03,0x01,0x07,0x00,0x03,0x10,
  1890. X 0x10,0x18,0x03,0x01,0x18,0x00,0x01,0x10,0x10,0x98,0x01,0x01,0xe0,0x00,0x01,
  1891. X 0x1c,0x10,0xb0,0x01,0x01,0x00,0x03,0x81,0x03,0x10,0xb0,0x01,0x01,0x00,0x1c,
  1892. X 0x61,0x00,0x10,0xe0,0x00,0x01,0x00,0x60,0x1d,0x00,0x30,0x60,0x00,0x01,0x00,
  1893. X 0x80,0x03,0x00,0xc0,0x40,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x01,
  1894. X 0x00,0x00,0x00,0x00,0x00,0x1c,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x60,0x00,
  1895. X 0x01,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x01,0x00,0x00,0x00,0x00,0x00,0x00,
  1896. X 0x0c,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x01,0x00,0x00,0x00,0x00,0x00,
  1897. X 0x00,0xc0,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
  1898. END_OF_FILE
  1899. if test 1919 -ne `wc -c <'vdm.icon'`; then
  1900.     echo shar: \"'vdm.icon'\" unpacked with wrong size!
  1901. fi
  1902. # end of 'vdm.icon'
  1903. fi
  1904. echo shar: End of archive 14 \(of 21\).
  1905. cp /dev/null ark14isdone
  1906. MISSING=""
  1907. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 ; do
  1908.     if test ! -f ark${I}isdone ; then
  1909.     MISSING="${MISSING} ${I}"
  1910.     fi
  1911. done
  1912. if test "${MISSING}" = "" ; then
  1913.     echo You have unpacked all 21 archives.
  1914.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1915. else
  1916.     echo You still need to unpack the following archives:
  1917.     echo "        " ${MISSING}
  1918. fi
  1919. ##  End of shell archive.
  1920. exit 0
  1921. --
  1922. Molecular Simulations, Inc.             mail: dcmartin@postgres.berkeley.edu
  1923. 796 N. Pastoria Avenue                  uucp: uwvax!ucbvax!dcmartin
  1924. Sunnyvale, California 94086             at&t: 408/522-9236
  1925.